package com.atguigu.gulimall.juc.demo;

import sun.awt.windows.ThemeReader;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

class VolatileData{
    volatile int number = 0;

    public void addTo60(){
        this.number = 60;
    }

    // 此时加了volatile不保证原子性
    public synchronized void add(){
        this.number++;
    }

    // 通过加sync
    // 使用原子类
    AtomicInteger atomicInteger = new AtomicInteger();
    public void addAtomic(){
        atomicInteger.getAndIncrement();
    }
}

public class VolatileDemo {
    /**
     * 主线程没有感知到 number 值得变化，主线程卡住
     *  各个线程都存在一份对该对象得副本
     * @param args
     */
    public static void main(String[] args) {
        VolatileData data = new VolatileData();
        for (int i = 0; i < 20 ; i++) {
            new Thread(()->{
                for (int j = 1; j <= 1000 ; j++) {
                    data.add();
                    data.addAtomic();
                }
            },String.valueOf(i)).start();
        }

        // 需要等待以上20个线程运行完成后再获取结果 main线程+gc线程
        while (Thread.activeCount() > 2){
            Thread.yield();
        }

        System.out.println(data.number);

//        seeOkVolatile();
    }

    private static void seeOkVolatile() {
        VolatileData data = new VolatileData();
        new Thread(()->{
            System.out.println("当前线程:"+Thread.currentThread().getName()+" 初始值: "+data.number);
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            data.addTo60();
            System.out.println("当前线程:"+Thread.currentThread().getName()+" 结果: "+data.number);
        }).start();

        while (data.number == 0){

        }
        System.out.println(Thread.currentThread().getName()+" 值："+data.number);
    }
}
